/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.flexengine.component;

import com.flexengine.input.InputManager;
import com.flexengine.utils.FontManager;
import com.flexengine.view.Graphics;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

/**
 * @author Luann R. Athayde
 * @version 1.0
 * @since 1.0
 */
public class TextField extends GameComponent implements HorizontalTextAlign {

    private volatile int mouseX = 0;
    private volatile int mouseY = 0;
    
    private String  text;
    private boolean selected;
    
    private int     columns;
    
    private Font    font;
    
    private Color   backgroundColor;
    private Color   foregroundColor;
    private Color   cursorColor;
    
    private Color   borderColor;
    private float   borderSize;
    
    private int     roundRectWidth;
    private int     roundRectHeight;
    
    private int     horizontalTextAlign;
    
    private int     maxLenght;
    
    // -------------------------------------------------------------------------
    private boolean blink;
    private int     blickCont;
    
    private boolean passwordField;
    // -------------------------------------------------------------------------
    private Rectangle2D       r2d;
    private FontRenderContext fontContext;
    
    private ArrayList<ActionListener> listeners;
    private int eventID;
    
    private float transparence;

    public TextField() {
        this("");
    }

    public TextField(String text) {
        super();
        this.text = text;
        this.passwordField = false;
        this.selected = false;
        this.columns = 0;
        this.font = FontManager.getFont(FontManager.defaultFont);
        this.backgroundColor = Color.LIGHT_GRAY;
        this.foregroundColor = Color.BLACK;
        this.cursorColor = Color.BLACK;
        this.borderColor = Color.WHITE;
        this.borderSize = 1;
        this.roundRectWidth = 0;
        this.roundRectHeight = 0;
        this.blink = false;
        this.blickCont = 0;
        this.size.setSize(100, 20);
        this.fontContext = new FontRenderContext(null, true, false);
        this.horizontalTextAlign = HORIZONTAL_ALIGN_LEFT;
        //this.customCursor = false;
        this.listeners = new ArrayList<>();
        this.eventID = 0;
        this.maxLenght = -1;
        this.transparence = 1f;
    }
    
    @Override
    public void update(Long time, Long totalTime) {
        if( blickCont >= 25 ) {
            blickCont = 0;
            blink = !blink;
        }
        blickCont++;
        // ---------------------------------------------------------------------
        mouseX = InputManager.getMouseX();
        mouseY = InputManager.getMouseY();
        // ---------------------------------------------------------------------
        
        if( InputManager.isMouseCliked(InputManager.MOUSE_BUTTON1) &&
                mouseX>x && mouseX<x+size.width &&
                mouseY>y && mouseY<y+size.height ) {
            selected = true;
        }
        else if( InputManager.isMouseCliked(InputManager.MOUSE_BUTTON1) &&
                (mouseX<x || mouseX>x+size.width ||
                mouseY<y || mouseY>y+size.height) ) {
            selected = false;
        }
        if( selected ) {
            if( InputManager.isKeyDown(InputManager.VK_BACK_SPACE) ) {
                if( text.length()>0 ) {
                    text = text.substring(0, text.length()-1);
                }
                InputManager.releaseKey(InputManager.VK_BACK_SPACE);
            }
            else if( InputManager.isKeyDown(InputManager.VK_ENTER) ) {
                for(int i=0;i<listeners.size();i++) {
                    listeners.get(i).actionPerformed(new ActionEvent(this, eventID, text, time, -1));
                    eventID++;
                }
                InputManager.releaseKey(InputManager.VK_ENTER);
            }
            else if( InputManager.getLastKeyChar()!=null ) {
                if( maxLenght>0 ) {
                    if( text.length()<maxLenght ) {
                        text += InputManager.getLastKeyChar();
                    }
                } else {
                    text += InputManager.getLastKeyChar();
                }
                InputManager.releaseKey(InputManager.getLastKeyCode());
            }
        }
    }
    
    @Override
    public void render(Graphics g) {
        //super.render(g);
        String textTmp = text;
        if( passwordField ) {
            textTmp = "";
            for(int i=0;i<text.length();i++) {
                textTmp += '#';
            }
        }
        r2d = font.getStringBounds(textTmp,fontContext);
        
        g.setFont(font);
        
        if( backgroundColor != null ) {
            g.setColor(backgroundColor);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, transparence));
            g.fillRoundRect((int)x, (int)y, size.width, size.height,roundRectWidth,roundRectHeight);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
        }
        
        if(borderColor!=null){
            g.setColor(borderColor);
            Stroke s = g.getStroke();
            if( borderSize>0 ) {
                g.setStroke(new BasicStroke(borderSize));
            }
            g.drawRoundRect((int)x, (int)y, size.width, size.height,roundRectWidth,roundRectHeight);
            g.setStroke(s);
        }
        
        if( foregroundColor!=null ) {
            g.setColor(foregroundColor);
        }
        else {
            g.setColor(Color.BLACK);
        }
        //g.drawString(text,(int)x+roundRectLeft/2,(int)y+font.getSize()-2);
        float xTmp = x+2f;
        if( horizontalTextAlign == HORIZONTAL_ALIGN_LEFT ) {
            xTmp+= roundRectWidth/2;
        }
        else if( horizontalTextAlign == HORIZONTAL_ALIGN_CENTER ) {
            xTmp += size.width/2-r2d.getWidth()/2;
        }
        else if(horizontalTextAlign == HORIZONTAL_ALIGN_RIGHT) {
            xTmp += (float)(size.width-r2d.getWidth())-roundRectWidth-3;
        }
        float yTmp = y;
        yTmp += r2d.getHeight()/2 + size.getHeight()/2;
        g.drawString(textTmp,(int)xTmp+2,(int)yTmp);
        
        if( cursorColor!=null ) {
            g.setColor(cursorColor);
        }
        else {
            g.setColor(Color.BLACK);
        }
        
        xTmp = x+2f;
        if( blink && selected && horizontalTextAlign == HORIZONTAL_ALIGN_LEFT ) {
            xTmp += r2d.getWidth()+3f;
            float xTmp2 = xTmp;
            if( font.isItalic() ) {
                xTmp += 8;
            }
            g.drawLine((int)xTmp+roundRectWidth/2, (int)y+3, (int)xTmp2+roundRectWidth/2, (int)y+size.height-6);
            if( font.isBold() ) {
                g.drawLine((int)xTmp+roundRectWidth/2+1, (int)y+3, (int)xTmp2+roundRectWidth/2+1, (int)y+size.height-6);
            }
        } else if(blink && selected && horizontalTextAlign == HORIZONTAL_ALIGN_RIGHT ) {
            xTmp += size.width-roundRectWidth;
            float xTmp2 = xTmp;
            if( font.isItalic() ) {
                xTmp += 8;
            }
            g.drawLine((int)xTmp, (int)y+3, (int)xTmp2, (int)y+size.height-6);
            if( font.isBold() ) {
                g.drawLine((int)xTmp+1, (int)y+3, (int)xTmp2+1, (int)y+size.height-6);
            }
        } else if(blink && selected && horizontalTextAlign == HORIZONTAL_ALIGN_CENTER ) {
            xTmp += size.width/2f+r2d.getWidth()/2f+4f;
            float xTmp2 = xTmp;
            if( font.isItalic() ) {
                xTmp += 8;
            }
            g.drawLine((int)xTmp, (int)y+3, (int)xTmp2, (int)y+size.height-6);
            if( font.isBold() ) {
                g.drawLine((int)xTmp+1, (int)y+3, (int)xTmp2+1, (int)y+size.height-6);
            }
        }
    }
    
    public void addEventListener(ActionListener event) {
        listeners.add(event);
    }
    
    public boolean removeListener(ActionListener event) {
        return listeners.remove(event);
    }
    
    public void clearListener() {
        listeners.clear();
    }
    
    @Override
    public int getHorizontalTextAlign() {
        return horizontalTextAlign;
    }

    @Override
    public void setHorizontalTextAlign(int horizontalAlign) {
        this.horizontalTextAlign = horizontalAlign;
    }

    public int getColumns() {
        return columns;
    }

    public void setColumns(int columns) {
        this.columns = columns;
    }

    public Font getFont() {
        return font;
    }

    public void setFont(Font font) {
        this.font = font;
    }

    public Color getBackgroundColor() {
        return backgroundColor;
    }

    public void setBackgroundColor(Color backgroundColor) {
        this.backgroundColor = backgroundColor;
    }

    public Color getForegroundColor() {
        return foregroundColor;
    }

    public void setForegroundColor(Color foregroundColor) {
        this.foregroundColor = foregroundColor;
    }

    public Color getCursorColor() {
        return cursorColor;
    }

    public void setCursorColor(Color cursorColor) {
        this.cursorColor = cursorColor;
    }

    public Color getBorderColor() {
        return borderColor;
    }

    public void setBorderColor(Color borderColor) {
        this.borderColor = borderColor;
    }

    public float getBorderSize() {
        return borderSize;
    }

    public void setBorderSize(float borderSize) {
        this.borderSize = borderSize;
    }

    public int getRoundRectWidth() {
        return roundRectWidth;
    }

    public void setRoundRectWidth(int roundRectWidth) {
        this.roundRectWidth = roundRectWidth;
    }

    public int getRoundRectHeight() {
        return roundRectHeight;
    }

    public void setRoundRectHeight(int roundRectHeight) {
        this.roundRectHeight = roundRectHeight;
    }

    public FontRenderContext getFontContext() {
        return fontContext;
    }

    public void setFontContext(FontRenderContext fontContext) {
        this.fontContext = fontContext;
    }

    public void setRoundRect(int roundRectLeft,int roundRectRight) {
        this.roundRectWidth = roundRectLeft;
        this.roundRectHeight = roundRectRight;
    }
    
    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        if( text == null ) {
            text = "";
        }
        this.text = text;
    }

    public int getMaxLenght() {
        return maxLenght;
    }

    public void setMaxLenght(int maxLenght) {
        this.maxLenght = maxLenght;
    }

    public Color getTextColor() {
        return foregroundColor;
    }

    public void setTextColor(Color textColor) {
        this.foregroundColor = textColor;
    }

    public void setPasswordField(boolean passwordField) {
        this.passwordField = passwordField;
    }

    public boolean isPasswordField() {
        return passwordField;
    }

    public void setTransparence(float transparence) {
        this.transparence = transparence;
    }

    public float getTransparence() {
        return transparence;
    }
    
}
